package com.zrrd.jt_admin.file.service.impl;

import com.zrrd.jt_admin.common.properties.MinIOConfigProperties;
import com.zrrd.jt_admin.file.service.FileStorageService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.RemoveObjectsArgs;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author ZhangYK
 * @version 8.0
 * @title MinIOFileStorageServiceImpl
 * @description
 * @create 2024/7/3 16:13
 */
@Slf4j
@Service
public class MinIOFileStorageServiceImpl implements FileStorageService {
    @Resource
    private MinioClient minioClient;

    @Resource
    private MinIOConfigProperties minIOConfigProperties;

    private static final String delimiter = "/";

    /**
     * 设置文件路径方法
     * @param dirPath
     * @param fileName
     * @return
     */
    private String builderFilePath(String dirPath, String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        //重新生成文件名
        //格式化时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        //把上传文件按照年月日进行分割 /2024/7/3/file
        stringBuilder.append(sdf.format(new Date())).append(delimiter);
        //如果路径不为null
        if (StringUtils.isNotBlank(dirPath)) {
            stringBuilder.append(dirPath).append(delimiter);
        }

        String imageName = UUID.randomUUID().toString().replaceAll("-", "");
        String suffix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
        //stringBuilder.append(fileName);
        stringBuilder.append(imageName).append(suffix);
        return stringBuilder.toString();
    }

    /**
     * todo 上传文件
     * @param prefix 文件前缀
     * @param fileName 文件名
     * @param inputStream 文件流
     * @return
     */
    @Override
    public String uploadImageFile(String prefix, String fileName, InputStream inputStream) {
        //获取完整路径
        String filePath = builderFilePath(prefix, fileName);
        try {
            //设置文件上传的文件配置信息
            PutObjectArgs imageProject = PutObjectArgs.builder()
                    .bucket(minIOConfigProperties.getBucket())
                    .contentType("image/jpeg")
                    .object(filePath)//文件路径
                    .stream(inputStream, inputStream.available(), -1)
                    .build();
            //上传图片
            minioClient.putObject(imageProject);
            //生成上传后的url
            StringBuilder fileUrl = new StringBuilder();
            //fileUrl.append(delimiter+minIOConfigProperties.getBucket());
            fileUrl.append(delimiter+filePath);
            //把文件url返回
            return fileUrl.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ServerException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                inputStream.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }

    @Override
    public void deleteFile(String fileUrl) {
        try {
            RemoveObjectArgs removeObjectArgs = RemoveObjectArgs
                    .builder()
                    .bucket(minIOConfigProperties.getBucket())
                    .object(fileUrl)
                    .build();
            log.info("图片删除成功>>>>>>>>>>>>>>"+fileUrl);
            minioClient.removeObject(removeObjectArgs);
        } catch (ServerException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteFiles(List<String> fileUrls) {

    }

    @Override
    public byte[] downloadFile(String fileUrl) {
        return new byte[0];
    }
}
